use crate::process::{proc::syscall::{SysResult, Syscall}, task::task::Task};

impl Task {
    fn arg_raw(&mut self, n: usize) -> usize {
        //let trapframe = unsafe { self.data.get().as_ref().unwrap().trapframe.as_ref().unwrap() };
        let trapframe = self.get_trap_frame();
        match n {
            0 => {trapframe.a0}
            1 => {trapframe.a1}
            2 => {trapframe.a2}
            3 => {trapframe.a3}
            4 => {trapframe.a4}
            5 => {trapframe.a5}
            _ => { panic!("n is larger than 5") }
        }
    }

    #[inline]
    fn arg_i32(&mut self, n: usize) -> i32 {
        self.arg_raw(n) as i32
    }

    /// Fetch a raw user virtual address from register value.
    /// Note: This raw address could be null,
    ///     and it might only be used to access user virtual address.
    #[inline]
    fn arg_addr(&mut self, n: usize) -> usize {
        self.arg_raw(n)
    }

}
impl Task {
    fn fork(&self) -> Result<usize, ()> {
        let current_process = unsafe { self.process.unwrap().as_ref().unwrap()};
        unimplemented!();
        // let pdata = self.data.get_mut();
        // let child = unsafe { PROC_MANAGER.alloc_proc().ok_or(())? };
        // let mut cexcl = child.excl.lock();
        // let cpid = cexcl.pid;
        // let cdata = unsafe { child.data.get().as_mut().unwrap() };
        // cdata.ustack_base = pdata.ustack_base;
        // // clone memory
        // let cpgt = cdata.pagetable.as_mut().unwrap();
        // let size = pdata.size;
        // if pdata.pagetable.as_mut().unwrap().uvm_copy(cpgt, size).is_err() {
        //     debug_assert_eq!(child.killed.load(Ordering::Relaxed), false);
        //     child.killed.store(false, Ordering::Relaxed);
        //     cdata.cleanup(cpid);
        //     cexcl.cleanup();
        //     return Err(())
        // }
        // cdata.size = size;

        // Ok(0)
    }
}
impl Task {
    fn sys_test(&mut self) -> SysResult{
        unimplemented!("syscall_test");
    }
    fn sys_fork(&mut self) -> SysResult {
        let ret = self.fork();

        #[cfg(feature = "trace_syscall")]
        println!("[{}].fork() = {:?}(pid)", self.excl.lock().pid, ret);

        ret
    }
}